/***************************************************************************
 *   Copyright (C) 2006 by Autostop team                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

///@file autopackets.h Defiitiona of packets used by pcnetlib

#ifndef AUTOPACKETS_H
#define AUTOPACKETS_H

#include "gnettypes.h"
#include "analyzer.h"    // for pimage_t 

// ----------------------------- GAutoPacket ----------------------------
/// Base class for all packets
class GAutoPacket : public GPacket
{
	Q_OBJECT
public:

	/// Packet types
	enum PacketType
	{
		PACKET_PARAMS	= MKWORD( 'a', 'u', 't', 'o' ),	///< New param value
		PACKET_XML_CONFIG,			///< Camera configuration file (xml)
		PACKET_MARKERS,
		PACKET_ROI,
		PACKET_REQUEST,				///< Request for data/value
		PACKET_REPLY_FRAME,			///< Request reply - param value
		PACKET_REPLY_XML_CONFIG,
		
		PACKET_UNKNOWN,				///< Unknown packet
		PACKET_LAST
	};

	// construction / destruction
	GAutoPacket() : GPacket() {}
	virtual ~GAutoPacket() {}

	// type query
	virtual PacketType packetType() const = 0;
    virtual GHeader header() const;

	// packet factory
	static GAutoPacket * createPacket( const GHeader& header );

private:
}; // !GAutoPacket
// ---------------------------------------------------------------------------





// ----------------------------- GAutoUnknown --------------------------------
/// Quasi-packet. Used to read uknown packets from stream.
class GAutoUnknown : public GAutoPacket
{
	Q_OBJECT
public:
	GAutoUnknown() : GAutoPacket() {}
	virtual ~GAutoUnknown() {}

	virtual PacketType packetType() const { return PACKET_UNKNOWN; }

protected:
	virtual void writeData( QDataStream & ) const {}
	virtual void readData( QDataStream & ) {}
	
}; // !GAutoUnknown
// ---------------------------------------------------------------------------




// ----------------------- GAutoParams ---------------------------------------
class GAutoParams : public GAutoPacket
{
	Q_OBJECT
			
public:
	GAutoParams() : GAutoPacket() {}
	virtual ~GAutoParams() {}
	
	virtual PacketType packetType() const { return PACKET_PARAMS; }
	
    void setParams( const QVariantMap & params ) { _params = params; }
    QVariantMap params() { return _params; }
	
protected:
	virtual void writeData( QDataStream & ) const;
	virtual void readData( QDataStream & );
	
private:
    QVariantMap _params; ///< Params values
	
}; // ! GAutoParams
// ---------------------------------------------------------------------------




// ----------------------- GAutoXmlConfig ------------------------------------
class GAutoXmlConfig : public GAutoPacket
{
	Q_OBJECT
			
public:
	GAutoXmlConfig() : GAutoPacket() {}
	virtual ~GAutoXmlConfig() {}
	
	// ----------------------------------------------------
	// GAutoXmlConfig specific 	
	QByteArray data() { return _data; }
	void setData( const QByteArray & data ) { _data = data; }
	
	virtual PacketType packetType() const { return PACKET_XML_CONFIG; }
	
protected:
	virtual void writeData( QDataStream & ) const;
	virtual void readData( QDataStream & );
	
private:
	QByteArray _data; ///< xml config files data 
	
}; // ! GAutoXmlConfig
// ---------------------------------------------------------------------------




// ----------------------- GAutoMarkers --------------------------------------
class GAutoMarkers : public GAutoPacket
{
	Q_OBJECT
			
public:
	GAutoMarkers() : GAutoPacket() {}
	virtual ~GAutoMarkers() {}
	
	// ----------------------------------------------------
	// packets specific 	
	pimage_t markers() { return _markers; }
	void setMarkers( const pimage_t markers ) { _markers = markers; }
	
	virtual PacketType packetType() const { return PACKET_MARKERS; }
	
protected:
	virtual void writeData( QDataStream & ) const;
	virtual void readData( QDataStream & );
	
private:
	pimage_t _markers; ///< markers image
	
}; // ! GAutoMarkers
// ---------------------------------------------------------------------------




// ----------------------- GAutoRoi ------------------------------------------
class GAutoRoi : public GAutoPacket
{
	Q_OBJECT
			
public:
	GAutoRoi() : GAutoPacket() {}
	virtual ~GAutoRoi() {}
	
	// ----------------------------------------------------
	// packets specific 	
	pimage_t roi() { return _roi; }
	void setRoi( const pimage_t roi ) { _roi = roi; }
	
	virtual PacketType packetType() const { return PACKET_ROI; }
	
protected:
	virtual void writeData( QDataStream & ) const;
	virtual void readData( QDataStream & );
	
private:
	pimage_t _roi; ///< roi image
	
}; // ! GAutoRoi
// ---------------------------------------------------------------------------





// ----------------------------- GAutoRequest --------------------------------
/// Request packet - used to ask for frame
/// Each request has its unique id, whcih will be used in reply packet,
/// To associate request with packet
class GAutoRequest : public GAutoPacket
{
	Q_OBJECT
public:

	/// Request types
	enum RequestType
	{
		REQUEST_FRAME,				///< param value request
		REQUEST_XML_CONFIG,
		REQUEST_PARAMS,
		
		REQUEST_INVALID,
		REQUEST_LAST
	};

	// construction / destruction
	
	GAutoRequest( RequestType type = REQUEST_INVALID, uint id = -1 );
	virtual ~GAutoRequest() {}

	// request - specific
	RequestType requestType() const { return _requestType; }
	quint32 requestId() const { return _requestId; }

	virtual PacketType packetType() const { return PACKET_REQUEST; }

protected:
	// serialization

	/// Serializes object
	virtual void writeData( QDataStream & out ) const;
	/// Reads object
	virtual void readData( QDataStream & in );
	
private:

	RequestType 	_requestType;		///< Request type
	quint32			_requestId;			///< Unique request id
	
}; // !GAutoRequest
// ---------------------------------------------------------------------------


// --------------------------- GAutoReply ------------------------------------
/// Base class for all reply packages. Contains the reqwust id field
/// Which allows to associate it with sepcified request packet
// TODO add error filed to trafer execution status and errro message to client
class GAutoReply : public GAutoPacket
{
	Q_OBJECT
public:
	GAutoReply( quint32 requestId = -1 )
		: GAutoPacket(), _requestId( requestId ) {}
	virtual ~GAutoReply() {}
	
	quint32 requestId() const { return _requestId; }

protected:
	quint32 _requestId;
}; // !GAutoReply
// ---------------------------------------------------------------------------




// ----------------------------- GAutoReplyFrame -----------------------------
/// Reqeust reply - frame
class GAutoReplyFrame : public GAutoReply
{
	Q_OBJECT
public:

	// construction / destruction
	GAutoReplyFrame( uint requestId = -1 )
		: GAutoReply( requestId ) {}
	virtual ~GAutoReplyFrame() {}

	// packet - specific
	quint16 width()const { return _width; }
	quint16 height()const { return _height; }
	const QByteArray & image() { return _image; }
	quint64 timestamp()const { return _timestamp; }
	
	void setWidth( const quint16 width ) { _width = width; }
	void setHeight( const quint16 height ) { _height = height; }
	void setImage( const QByteArray & image ) { _image = image; }
	void setTimestamp ( const quint64 timestamp ) { _timestamp = timestamp; }
	
	virtual PacketType packetType() const { return PACKET_REPLY_FRAME; }

protected:
	// serialization

	/// Serializes object
	virtual void writeData( QDataStream & out ) const;
	/// Reads object
	virtual void readData( QDataStream & in );

private:
	quint16 	_width;
	quint16 	_height;
	QByteArray	_image;
	quint64		_timestamp;
	
}; // !GAutoReplyFrame
// ---------------------------------------------------------------------------




// ------------------------- GAutoReplyXmlConfig -----------------------------
/// Reqeust reply - frame
class GAutoReplyXmlConfig : public GAutoReply
{
	Q_OBJECT
public:

	// construction / destruction
	GAutoReplyXmlConfig( uint requestId = -1 )
		: GAutoReply( requestId ) {}
	virtual ~GAutoReplyXmlConfig() {}

	// packet - specific
	QByteArray & data() { return _data; }
	void setData( const QByteArray & data ) { _data = data; }
	
	virtual PacketType packetType() const { return PACKET_REPLY_FRAME; }

protected:
	// serialization

	/// Serializes object
	virtual void writeData( QDataStream & out ) const;
	/// Reads object
	virtual void readData( QDataStream & in );

private:
	QByteArray _data;
	
}; // !GAutoReplyXmlConfig
// ---------------------------------------------------------------------------




#endif // !AUTOPACKETS_H

// eof
